
/*
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0+
 * License-Filename: LICENSE
 * Copyright tuxsee authors
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <locale.h>
#include <time.h>

#ifdef HAVE_MTRACE
#include <mcheck.h>
#endif

#include "splay-tree.h"
#include "options.h"
#include "mem.h"
#include "color.h"
#include "maingtk.h"
#include "lmain.h"
#include "nes.h"
#include "main.h"

/* forward */
static void console_saveas (char *infile, char *outfile);

/* */
int
main (int argc, char *argv[])
{

  /* only when env setting MALLOC_TRACE is set
   * this mtrace() does have effect and a logfile
   * is created with malloc/free/realloc usage
   * that file can be changed to human readable
   * with the mtrace perl script in /usr/bin
   * mtrace is a glibc feature
   */
#ifdef HAVE_MTRACE
  mtrace ();
#endif

  /*
   * using srand and rand because of mingw issue:
   * or in mingw headers put
   * #define srandom srand
   * #define random rand
   */

  /* */
  srand ((unsigned int) time (NULL));

  /* check against few values determined by configure.ac about this computer */

  /* The size of `char *', as computed by sizeof. */
  if ((SIZEOF_CHAR_P > sizeof (splay_tree_key)) ||
      /* The size of `int', as computed by sizeof. */
      (SIZEOF_INT > sizeof (splay_tree_key)) ||
      /* The size of `void *', as computed by sizeof. */
      (SIZEOF_VOID_P > sizeof (splay_tree_key)))
    {
      /* splay() cannot work with too small typedef for splay_tree_key */
      printf ("%s:%s() sizeof splay_tree_key (%d) is too low for this computer now adjust the setting in splay-tree.h to fix this issue.\n", argv[0],
	      __FUNCTION__, (int) sizeof (splay_tree_key));
      return (0);
    }

  /* locale */
  setlocale (LC_ALL, "");

  /* commandline options */
  commandline_options (argc, argv);

  if (option_filename && option_outfilename)
    {
      console_saveas (option_filename, option_outfilename);
    }
  else
    {
      /* run gtk+ gui */
      maingtk (argc, argv);
    }

  /* clear memory */
  colorcode_clear ();

  prepare4newdata ();

  myfinalmemcheck ();

  /* oke status */
  exit (0);
}

/* run as console tool writing image */
static void
console_saveas (char *infile, char *outfile)
{
  char *p = NULL;

  /* check for file extension png at output file */
  p = strrchr (outfile, '.');

  if (p == NULL)
    {
      return;
    }

  /* png output using gtk cairo lib may crash libpng
   * and cannot generate big images > 32kx32k px.
   * then use svg file extension and a good svg viewer.
   * also posible to run drawing multiple times for few
   * parts of the graph and incrementally write the
   * image data per group of image lines with libpng/jpg
   * or generate many multiple images and use one of the
   * GPL'ed server software packages to use it in browser
   * as if it is one giant big image.
   */
  if (strcmp (p, ".png") == 0)
    {
      maingtk_saveaspng (infile, outfile);
    }
  else if (strcmp (p, ".svg") == 0)
    {
      maingtk_saveassvg (infile, outfile);
    }
  else
    {
      fprintf (stderr, "%s(): unsupported file extension %s try png or svg\n", __FUNCTION__, p);
    }

  return;
}

/* calculate node text size wrapping to Linux gtk */
void
textsizes (void)
{
  maingtk_textsizes ();
  return;
}

/* update status text in gui */
void
update_statusline (char *text)
{
  update_status_text (text);
  return;
}

/* scan printf args */
static void
staticmgprintf (const char *fmt, va_list ap)
{
  /* to implement */
  if (fmt)
    {
    }
  if (ap)
    {
    }
  return;
}

/* printf used for log messages to stdout or option_logfile */
void
mgprintf (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  staticmgprintf (fmt, ap);
  va_end (ap);
  return;
}

void
mghexdump (FILE * f, unsigned char *data, unsigned long length)
{
  unsigned long i = 0;
  int j = 0;
  unsigned char d = 0;

  j = 0;

  for (i = 0; i < length; i++)
    {
      d = (unsigned char) (data[i]);
      fprintf (f, "%02x ", d);

      j = (j + 3);

      if (!((i + 1) % 5))
	{
	  printf (" ");
	  j = (j + 1);
	}

      if (j >= 128)
	{
	  printf ("\n");
	  j = 0;
	}
    }

  if (j)
    {
      printf ("\n");
    }

  return;
}

/* */
char *
mgint2human (int num)
{
  /* to imp-lement */
  if (num)
    {
    }
  return ("");
}


/* end */

/*
 * Local Variables:
 * mode: C
 * tab-width: 8
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * ex: shiftwidth=4 tabstop=8
 */
